using System;
using System.Web;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web.Configuration;
using System.Web.Mvc;
using System.Web.Security;
using System.IO;

using MvcCms.Service.Code.Wiki;
using MvcCms.Web.ViewModels;
using WikiPlex;
using WikiPlex.Formatting;
using MvcCms.Data;
using MvcCms.Service.Code;
using MvcCms.Service.Cache;
using MvcCms.Service;
using MvcCms.Service.Validation;
using MvcCms.Data.Pagination;

namespace MvcCms.Web.Controllers
{
    public class BackOfficeController  : MvcCms.Service.Code.BaseClasses.MvcCmsControllerBase
    {
        #region Constructors

        private readonly IAccountService _accountService;
        private readonly ICacheService _cacheService;
        private readonly ICmsService _cmsService;
        private readonly IMiscService _miscService;
        private readonly IPortalService _portalService;
        private readonly IWikiEngine _wikiEngine;


        public BackOfficeController(IWikiEngine wikiEngine, IPortalService portalService, IAccountService acctService,
                                    ICmsService cmsService, IMiscService miscservice, ICacheService cacheService)
        {
            _portalService = portalService;
            _accountService = acctService;
            _cmsService = cmsService;
            _miscService = miscservice;
            _cacheService = cacheService;
            _wikiEngine = wikiEngine;
        }

        #endregion

        #region Cms Methods
        [Authorize(Roles = "Editor")]
        public ActionResult Cms()
        {
            var contributors = _accountService.ListContributors();
            ViewData["UserID"] = new SelectList(contributors, "UserID", "UserName");

            var languages = _miscService.ListLanguages();
            var currentPortal = _cacheService.GetCurrentPortal();
            var categoriesHierarchy = _cmsService.ListCategoriesHierarchy();
            var categoriesTemp = new CategoriesAjax();
            foreach (ContentCategory category in categoriesHierarchy)
            {
                if (category.ParentCategory == null)
                {
                    categoriesTemp.Add(category);
                }
            }
            var model = new BackOfficeModel
            {
                _ContentCategories = categoriesTemp,
                _Languages = languages,
                _Portal = currentPortal
            };
            ViewData["defaultLangId"] = currentPortal.DefaultLanguage.LanguageID;
            ViewData["PageTitle"] = "CMS Console";
            if (currentPortal.UsesWikiForCMS)
            {
                return View("CmsWithWiki", "cms", model);
            }
            else
            {
                return View("Cms", "cms", model);
            }
        }

        private static void ResetAppAuto()
        {
            Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
            var httpRuntimeSection = (HttpRuntimeSection)config.GetSection("system.web/httpRuntime");
            httpRuntimeSection.Enable = false;
            config.Save(ConfigurationSaveMode.Minimal);

            httpRuntimeSection.Enable = true;
            config.Save(ConfigurationSaveMode.Minimal);
        }
        #endregion

        #region Portal Admin Methods

        [Authorize(Roles = "Admin, Editor")]
        public ActionResult ManageRedirects()
        {
            var redirects = _cmsService.ListRedirects();
            var model = new BackOfficeModel
            {
                _Redirects = redirects
            };
            ViewData["PageTitle"] = "Manage Redirects";
            return View(model);
        }

        [Authorize(Roles = "PortalAdmin")]
        public ActionResult ManageLanguages()
        {
            ViewData["Message"] = "";
            IEnumerable<Language> languages = _cacheService.ListLanguages();
            var model = new BackOfficeModel
            {
                _Languages = languages
            };
            ViewData["PageTitle"] = "Manage Languages";
            return View(model);
        }

        [Authorize(Roles = "PortalAdmin")]
        public ActionResult EditLanguage(int id)
        {
            ViewData["Message"] = "";
            Language language = _cacheService.GetLanguage(id);
            var model = new BackOfficeModel
            {
                _Language = language
            };

            ViewData["PageTitle"] = "Edit Language";
            return View(model);
        }

        [Authorize(Roles = "PortalAdmin")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditLanguage(Language editedLanguage)
        {
            Language languageToEdit = _miscService.GetLanguage(editedLanguage.LanguageID);

            languageToEdit.LanguageName = editedLanguage.LanguageName;
            languageToEdit.IconName = editedLanguage.IconName;
            languageToEdit.PathID = editedLanguage.PathID;

            if (_miscService.EditLanguage(languageToEdit))
            {
                ViewData["Message"] = "Update Successfull";
            }

            var model = new BackOfficeModel
            {
                _Language = languageToEdit
            };

            return View(model);
        }

        [Authorize(Roles = "PortalAdmin")]
        public ActionResult CreateLanguage([Bind(Exclude = "LanguageID")] Language languageToCreate)
        {
            ViewData["PageTitle"] = "Create Language";
            ViewData["message"] = "";

            if (languageToCreate.LanguageName != null)
            {
                if (_miscService.CreateLanguage(languageToCreate))
                {
                    ViewData["message"] = "Insert Successful";
                }

                return View("CreateLanguage");
            }

            return View("CreateLanguage");
        }

        [Authorize(Roles = "PortalAdmin")]
        public ActionResult ManagePortals(int? id)
        {
            if (Session["message"] != null)
            {
                ViewData["Message"] = Session["message"];
                Session["message"] = null;
            }
            else
            {
                ViewData["Message"] = "";
            }
            if (id != null)
            {
                Portal portalToDelete = _portalService.GetPortal(id.GetValueOrDefault());
                _portalService.DeletePortal(portalToDelete);
            }

            IEnumerable<Portal> portals = _portalService.ListPortals();
            var model = new BackOfficeModel
            {
                _Portals = portals
            };
            ViewData["PageTitle"] = "Manage Portals";
            return View(model);
        }

        [Authorize(Roles = "PortalAdmin, Admin")]
        public ActionResult EditPortal(int? id)
        {
            if (!Roles.IsUserInRole("PortalAdmin"))
            {
                var user = _accountService.GetUser();
                id = user.Portal.PortalID;
            }
            ViewData["Message"] = "";
            Portal portal = _portalService.GetPortal(id.GetValueOrDefault());

            IEnumerable<PortalResourceType> portalresources = _portalService.ListPortalResourceTypes();

            var model = new BackOfficeModel
            {
                _PortalResourceTypes = portalresources,
                _Portal = portal
            };

            ViewData["PageTitle"] = "Edit Portal";
            return View(model);
        }

        [Authorize(Roles = "PortalAdmin, Admin")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditPortal(Portal editedPortal)
        {
            Portal portalToEdit = _portalService.GetPortal(editedPortal.PortalID);
            ViewData["Message"] = "";
            if (portalToEdit.Name != "Default")
            {
                portalToEdit.Name = editedPortal.Name;
            }

            portalToEdit.URLAuthority = editedPortal.URLAuthority;
            portalToEdit.AdminEmail = editedPortal.AdminEmail;
            portalToEdit.DisplayName = editedPortal.DisplayName;
            portalToEdit.SkinName = editedPortal.SkinName;
            portalToEdit.PortalAdmin = _accountService.GetUser();
            portalToEdit.UseFullText = editedPortal.UseFullText;
            portalToEdit.UsesWikiForCMS = editedPortal.UsesWikiForCMS;
            portalToEdit.AllowPageWikiHtmlSwitch = editedPortal.AllowPageWikiHtmlSwitch;
            portalToEdit.AllowOpenIdRegistration = editedPortal.AllowOpenIdRegistration;
            portalToEdit.TimezoneOffset = editedPortal.TimezoneOffset;
            portalToEdit.IsRazor = editedPortal.IsRazor;

            if (_portalService.EditPortal(portalToEdit))
            {
                ViewData["Message"] = "Update Successfull";
            }
            IEnumerable<PortalResourceType> portalresources = _portalService.ListPortalResourceTypes();
            var model = new BackOfficeModel
            {
                _PortalResourceTypes = portalresources,
                _Portal = portalToEdit
            };

            return View(model);
        }

        [Authorize(Roles = "PortalAdmin")]
        public ActionResult CreatePortal(int? languageid, [Bind(Exclude = "PortalID")] Portal portalToCreate)
        {
            ViewData["PageTitle"] = "Create Portal";
            ViewData["message"] = "";
            IEnumerable<Language> languages = _cacheService.ListLanguages();
            ViewData["LanguageID"] = new SelectList(languages, "LanguageID", "LanguageName");

            if (portalToCreate.Name != null)
            {
                portalToCreate.EditDate = DateTime.Now;
                portalToCreate.PortalAdmin = _accountService.GetUser();

                var language = _miscService.GetLanguage(languageid.GetValueOrDefault());
                portalToCreate.DefaultLanguage = language;

                if (_portalService.CreatePortal(portalToCreate))
                {
                    ResetAppAuto();
                    Session["message"] = "Insert Successful";
                    return Redirect("/backoffice/manageportals");
                }
            }

            return View("CreatePortal");
        }

        #endregion

        #region Portal Resource Methods

        [Authorize(Roles = "PortalAdmin, Admin")]
        public ActionResult EditPortalResource(int id, int routeval)
        {
            ViewData["PageTitle"] = "Edit Portal Resource";
            ViewData["Message"] = "";
            PortalResource portalresource = _portalService.GetPortalResource(routeval, id);
            if (portalresource == null)
            {
                return Redirect("/backoffice/CreatePortalResource/" + id + "/" + routeval);
            }
            var model = new BackOfficeModel
            {
                _PortalResource = portalresource
            };

            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "PortalAdmin, Admin")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditPortalResource(PortalResource editedPortalResource)
        {
            ViewData["PageTitle"] = "Edit Portal Resource";
            ViewData["Message"] = "";
            PortalResource portalResourceToEdit = _portalService.GetPortalResource(editedPortalResource.PortalResourceID);
            portalResourceToEdit.Body = editedPortalResource.Body;
            portalResourceToEdit.PortalAdmin = _accountService.GetUser();
            if (_portalService.EditPortalResource(portalResourceToEdit))
            {
                ViewData["Message"] = "Update Successfull";
            }

            var model = new BackOfficeModel
            {
                _PortalResource = portalResourceToEdit
            };

            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "PortalAdmin, Admin")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult CreatePortalResource(
            [Bind(Exclude = "PortalResourceID")] PortalResource portalresourceToCreate)
        {
            ViewData["PageTitle"] = "Create Portal Resource";
            ViewData["message"] = "";
            PortalResourceType restype =
                _portalService.GetPortalResourceType(portalresourceToCreate.PortalResourceType.PortalResourceTypeID);
            ViewData["type"] = restype.Name;
            if (portalresourceToCreate.Body != null)
            {
                var user = _accountService.GetUser();
                portalresourceToCreate.EditDate = DateTime.Now;
                portalresourceToCreate.PortalAdmin = _accountService.GetUser(user.UserID);
                portalresourceToCreate.ResourceName = restype.Name;
                portalresourceToCreate.PortalResourceType.Name = restype.Name;
                portalresourceToCreate.Portal.PortalAdmin = _accountService.GetUser(user.UserID);
                if (_portalService.CreatePortalResource(portalresourceToCreate))
                {
                    Session["message"] = "Insert Successful";
                    return Redirect("/backoffice/manageportals");
                }
            }
            return View();
        }

        [Authorize(Roles = "PortalAdmin, Admin")]
        public ActionResult CreatePortalResource(int id, int routeval)
        {
            ViewData["PageTitle"] = "Create Portal Resource";
            ViewData["message"] = "";
            PortalResourceType restype = _portalService.GetPortalResourceType(id);
            Portal portal = _portalService.GetPortal(routeval);
            ViewData["restype"] = restype.Name;
            ViewData["restypeid"] = restype.PortalResourceTypeID;
            ViewData["PortalID"] = portal.PortalID;

            return View();
        }

        #endregion

        #region Module Methods

        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult ManageModules(int? id)
        {
            if (id != null)
            {
                _cmsService.DeleteModule(id.GetValueOrDefault());
                return Redirect("/backoffice/ManageModules");
            }
            var model = new BackOfficeModel
            {
                _Modules = _cmsService.ListModules()
            };
            ViewData["PageTitle"] = "Manage Modules";
            return View(model);
        }

        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult ManageWidgets(int? id)
        {
            if (id != null)
            {
                _cmsService.DeleteWidget(id.GetValueOrDefault());
                return Redirect("/backoffice/ManageWidgets");
            }
            var model = new BackOfficeModel
            {
                _Widgets = _cmsService.ListWidgets()
            };
            ViewData["PageTitle"] = "Manage Widgets";
            return View(model);
        }

        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult ManageWeightedContent(int? id)
        {
            if (id != null)
            {
                _cmsService.DeleteWeightedContent(id.GetValueOrDefault());
                return Redirect("/backoffice/ManageWeightedContent");
            }
            var model = new BackOfficeModel
            {
                _WeightedContents = _cmsService.ListWeightedContents()
            };
            ViewBag.Title = "Manage Weighted Content";
            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult EditModule(int? id, string allPagesValue, int? categoryId, int? contentpageId,
               Module moduleToEdit, int? weightedContentID, bool? hideIfAuthenticated, int? weight, string allowedRoles, WeightedContentModule editedSettings)
        {
            ViewData["Message"] = "";
            string[] allowedRolesArr = new string[0];
            if (!string.IsNullOrEmpty(allowedRoles))
            {
                allowedRolesArr = allowedRoles.Split(',');
            }
            WeightedContentModule settingsToEdit = null;
            if (moduleToEdit.Title != null)
            {
                Module original = _cmsService.GetModule(moduleToEdit.ModuleID);
                if (!moduleToEdit.IsForWeightedContent)
                {
                    if (allPagesValue == "All")
                    {
                        original.AllPages = true;
                        original.ContentCategory = null;
                        original.ContentPage = null;
                    }
                    else if (allPagesValue == "Cat")
                    {
                        original.ContentCategory = _cmsService.GetContentCategory(categoryId.GetValueOrDefault());
                        original.ContentPage = null;
                        original.AllPages = false;
                    }
                    else
                    {
                        original.ContentPage = _cmsService.GetContentPage(contentpageId.GetValueOrDefault());
                        original.ContentCategory = null;
                        original.AllPages = false;
                    }
                }
                settingsToEdit = original.WeightedContentsSettings.FirstOrDefault();
                original.Title = moduleToEdit.Title.Trim();
                original.Importance = moduleToEdit.Importance;
                original.Active = moduleToEdit.Active;
                original.AjaxLoadURL = moduleToEdit.AjaxLoadURL;
                original.Description = moduleToEdit.Description;
                original.HTML = moduleToEdit.HTML;
                original.UseAjaxLoadURL = moduleToEdit.UseAjaxLoadURL;
                original.GetScript = moduleToEdit.GetScript;

                if (!original.IsForWeightedContent)
                {
                    original.TargetDiv = moduleToEdit.TargetDiv.TryTrim();
                }
                else
                {
                    var weightedContent = _cmsService.GetWeightedContent(weightedContentID.GetValueOrDefault());
                    if (original.WeightedContentsSettings.Count() == 0)
                    {
                        var newWeightedContentModule = new WeightedContentModule
                        {
                            WeightedContent = weightedContent,
                            Weight = weight.GetValueOrDefault(),
                            HideIfAuthenticated = hideIfAuthenticated.GetValueOrDefault(),
                            ShowOnlyForRolesEnabled = false,
                            Module = original,
                            TransitionHideEffect = editedSettings.TransitionHideEffect,
                            TransitionShowEffect = editedSettings.TransitionShowEffect,
                            ShowDuration = editedSettings.ShowDuration,
                            HideDuration = editedSettings.HideDuration
                        };
                    }
                    else
                    {
                        settingsToEdit.WeightedContent = weightedContent;
                        settingsToEdit.Weight = weight.GetValueOrDefault();
                        settingsToEdit.HideIfAuthenticated = hideIfAuthenticated.GetValueOrDefault();
                        settingsToEdit.TransitionHideEffect = editedSettings.TransitionHideEffect;
                        settingsToEdit.TransitionShowEffect = editedSettings.TransitionShowEffect;
                        settingsToEdit.ShowDuration = editedSettings.ShowDuration;
                        settingsToEdit.HideDuration = editedSettings.HideDuration;
                    }
                    if (allowedRolesArr.Length > 0)
                    {
                        //add new roles
                        for (int i = 0; i < allowedRolesArr.Length; i++)
                        {
                            string loweredRoleName = allowedRolesArr[i].ToLower();
                            var roleExists = settingsToEdit.AllowedRoles.Where(r => r.RoleName.Equals(loweredRoleName)).FirstOrDefault();
                            if (roleExists == null)
                            {
                                var roleToAdd = _accountService.GetRole(loweredRoleName);
                                if (roleToAdd != null)
                                {
                                    settingsToEdit.AllowedRoles.Add(roleToAdd);
                                }
                            }
                        }
                        //remove roles
                        foreach (var role in settingsToEdit.AllowedRoles)
                        {
                            var roleExists = allowedRolesArr.Where(r => r.ToLower().Equals(role.LoweredRoleName));
                            if (roleExists == null)
                            {
                                settingsToEdit.AllowedRoles.Remove(role);
                            }
                        }
                        settingsToEdit.ShowOnlyForRolesEnabled = true;
                    }
                    else
                    {
                        if (settingsToEdit != null)
                        {
                            if (settingsToEdit.AllowedRoles.Count > 0)
                            {
                                settingsToEdit.AllowedRoles.Clear();
                            }
                            settingsToEdit.ShowOnlyForRolesEnabled = false;
                        }
                    }
                }
                _cmsService.EditModule(original);
                ViewData["Message"] = "The module was edited.";
                moduleToEdit = original;
            }
            else
            {
                moduleToEdit = _cmsService.GetModule(id.GetValueOrDefault());
                settingsToEdit = moduleToEdit.WeightedContentsSettings.FirstOrDefault();
            }
            int tempPageId = 0;
            int tempCategoryId = 0;
            if (moduleToEdit.ContentPage != null)
            {
                tempPageId = moduleToEdit.ContentPage.ContentPageID;
            }
            if (moduleToEdit.ContentCategory != null)
            {
                tempCategoryId = moduleToEdit.ContentCategory.CategoryID;
            }
            IEnumerable<DTOContentPageForEditor> pages = _cmsService.ListPages();
            ViewData["ContentPageID"] = new SelectList(pages.OrderBy(x => x.Title), "ContentPageID", "Title", tempPageId);
            IEnumerable<ContentCategory> cats = _cmsService.ListCategories();
            ViewData["CategoryID"] = new SelectList(cats.OrderBy(x => x.Path), "CategoryID", "Path", tempCategoryId);

            //need a dropdown for active weighted content this widget can be applied to
            var allWeightedContent = _cmsService.ListWeightedContents().Where(w => w.IsModuleType); ;
            if (settingsToEdit == null)
            {
                ViewData["WeightedContentID"] = new SelectList(allWeightedContent.OrderBy(x => x.Title), "WeightedContentID", "Title");
            }
            else
            {
                ViewData["WeightedContentID"] = new SelectList(allWeightedContent.OrderBy(x => x.Title), "WeightedContentID", "Title", settingsToEdit.WeightedContentID);
            }

            var model = new BackOfficeModel
            {
                _Module = moduleToEdit
            };
            ViewData["PageTitle"] = "Edit Module";
            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult CreateModule(int? contentPageId, string allPagesValue, int? categoryId,
                                         [Bind(Exclude = "ModuleID")] Module moduleToCreate)
        {
            ViewData["Message"] = "";

            if (moduleToCreate.Title != null)
            {
                moduleToCreate.AllPages = false;
                moduleToCreate.AddedDate = DateTime.Now;
                moduleToCreate.Importance = 0;
                if (!moduleToCreate.IsForWeightedContent)
                {
                    if (allPagesValue == "All")
                    {
                        moduleToCreate.AllPages = true;
                    }
                    else if (allPagesValue == "Cat")
                    {
                        moduleToCreate.ContentCategory = _cmsService.GetContentCategory(categoryId.GetValueOrDefault());
                    }
                    else
                    {
                        moduleToCreate.ContentPage = _cmsService.GetContentPage(contentPageId.GetValueOrDefault());
                    }
                }
                _cmsService.CreateModule(moduleToCreate);
                return Redirect("/backoffice/ManageModules");
            }
            var pages = _cmsService.ListPages();
            ViewData["ContentPageID"] = new SelectList(pages.OrderBy(x => x.Title), "ContentPageID", "Title");
            var cats = _cmsService.ListCategories();
            ViewData["CategoryID"] = new SelectList(cats.OrderBy(x => x.Path), "CategoryID", "Path");

            var model = new BackOfficeModel
            {
                _Module = moduleToCreate
            };
            ViewData["PageTitle"] = "Create Module";
            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult CreateWidget(string allPagesValue, int? categoryId, int? contentpageId,
                                         [Bind(Exclude = "ModuleID")] Widget widgetToCreate)
        {
            ViewData["Message"] = "";
            if (widgetToCreate.Title != null)
            {
                widgetToCreate.AllPages = false;
                widgetToCreate.ContentCategoryID = null;
                widgetToCreate.ContentPageID = null;
                widgetToCreate.AddedDate = DateTime.Now;
                if (!widgetToCreate.IsForWeightedContent)
                {
                    if (allPagesValue == "All")
                    {
                        widgetToCreate.AllPages = true;
                    }
                    else if (allPagesValue == "Cat")
                    {
                        widgetToCreate.ContentCategoryID = categoryId.GetValueOrDefault();
                    }
                    else if (allPagesValue == "Page")
                    {
                        widgetToCreate.ContentPageID = contentpageId.GetValueOrDefault();
                    }
                }
                widgetToCreate.AdminUser = _accountService.GetUser();
                _cmsService.CreateWidget(widgetToCreate);
                return Redirect("/backoffice/ManageWidgets");
            }
            var pages = _cmsService.ListPages();
            ViewData["ContentPageID"] = new SelectList(pages.OrderBy(x => x.Title), "ContentPageID", "Title");
            var cats = _cmsService.ListCategories();
            ViewData["CategoryID"] = new SelectList(cats.OrderBy(x => x.Path), "CategoryID", "Path");

            var model = new BackOfficeModel
            {
                _Widget = widgetToCreate
            };
            ViewData["PageTitle"] = "Create Widget";
            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult CreateWeightedContent(int? contentpageid, string allPagesValue, int? categoryId,
                                         [Bind(Exclude = "ModuleID")] WeightedContent weightedContentToCreate)
        {
            ViewBag.Message = "";

            weightedContentToCreate.AddedDate = DateTime.Now;
            if (weightedContentToCreate.Title != null)
            {
                weightedContentToCreate.AdminUser = _accountService.GetUser();
                _cmsService.CreateWeightedContent(weightedContentToCreate);
                return Redirect("/backoffice/ManageWeightedContent");
            }

            var model = new BackOfficeModel
            {
                _WeightedContent = weightedContentToCreate
            };
            ViewBag.Title = "Create WeightedContent";
            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult EditWidget(int? id, string allPagesValue, int? categoryId, int? contentpageId,
               Widget widgetToEdit, int? weightedContentID, bool? hideIfAuthenticated, int? weight, string allowedRoles)
        {
            ViewData["Message"] = "";
            string[] allowedRolesArr = new string[0];
            if (!string.IsNullOrEmpty(allowedRoles))
            {
                allowedRolesArr = allowedRoles.Split(',');
            }

            WeightedContentWidget settingsToEdit = null;
            if (widgetToEdit.Title != null)
            {
                var original = _cmsService.GetWidget(widgetToEdit.WidgetID);
                if (!widgetToEdit.IsForWeightedContent)
                {
                    if (allPagesValue == "All")
                    {
                        original.AllPages = true;
                        widgetToEdit.ContentCategoryID = null;
                        widgetToEdit.ContentPageID = null;
                    }
                    else if (allPagesValue == "Cat")
                    {
                        widgetToEdit.ContentCategoryID = categoryId.GetValueOrDefault();
                        widgetToEdit.ContentPageID = null;
                        original.AllPages = false;
                    }
                    else
                    {
                        widgetToEdit.ContentPageID = contentpageId.GetValueOrDefault();
                        widgetToEdit.ContentCategoryID = null;
                        original.AllPages = false;
                    }
                }

                settingsToEdit = original.WeightedContentsSettings.FirstOrDefault();
                original.Title = widgetToEdit.Title.Trim();
                original.Active = widgetToEdit.Active;
                original.Description = widgetToEdit.Description;
                original.HTML = widgetToEdit.HTML;
                original.AdminUser = _accountService.GetUser();
                original.ZoneName = widgetToEdit.ZoneName.TryTrim();

                if (!original.IsForWeightedContent)
                {
                    original.TargetDiv = widgetToEdit.TargetDiv;
                }
                else
                {
                    var weightedContent = _cmsService.GetWeightedContent(weightedContentID.GetValueOrDefault());
                    if (original.WeightedContentsSettings.Count() == 0)
                    {
                        var newWeightedContentModule = new WeightedContentWidget
                        {
                            WeightedContent = weightedContent,
                            Weight = weight.GetValueOrDefault(),
                            HideIfAuthenticated = hideIfAuthenticated.GetValueOrDefault(),
                            ShowOnlyForRolesEnabled = false,
                            Widget = original
                        };
                    }
                    else
                    {
                        settingsToEdit.WeightedContent = weightedContent;
                        settingsToEdit.Weight = weight.GetValueOrDefault();
                        settingsToEdit.HideIfAuthenticated = hideIfAuthenticated.GetValueOrDefault();
                    }
                    if (allowedRolesArr.Length > 0)
                    {
                        //add new roles
                        for (int i = 0; i < allowedRolesArr.Length; i++)
                        {
                            string loweredRoleName = allowedRolesArr[i].ToLower();
                            var roleExists = settingsToEdit.AllowedRoles.Where(r => r.RoleName.Equals(loweredRoleName)).FirstOrDefault();
                            if (roleExists == null)
                            {
                                var roleToAdd = _accountService.GetRole(loweredRoleName);
                                if (roleToAdd != null)
                                {
                                    settingsToEdit.AllowedRoles.Add(roleToAdd);
                                }
                            }
                        }
                        //remove roles
                        foreach (var role in settingsToEdit.AllowedRoles)
                        {
                            var roleExists = allowedRolesArr.Where(r => r.ToLower().Equals(role.LoweredRoleName));
                            if (roleExists == null)
                            {
                                settingsToEdit.AllowedRoles.Remove(role);
                            }
                        }
                        settingsToEdit.ShowOnlyForRolesEnabled = true;
                    }
                    else
                    {
                        //remove roles
                        if (settingsToEdit != null)
                        {
                            if (settingsToEdit.AllowedRoles.Count > 0)
                            {
                                settingsToEdit.AllowedRoles.Clear();
                            }
                            settingsToEdit.ShowOnlyForRolesEnabled = false;
                        }
                    }
                }
                _cmsService.EditWidget(original);
                ViewData["Message"] = "The widget was edited.";
                widgetToEdit = original;
            }
            else
            {
                widgetToEdit = _cmsService.GetWidget(id.GetValueOrDefault());
                settingsToEdit = widgetToEdit.WeightedContentsSettings.FirstOrDefault();
            }
            int tempPageId = 0;
            int tempCategoryId = 0;
            if (widgetToEdit.Page != null)
            {
                tempPageId = widgetToEdit.Page.ContentPageID;
            }
            if (widgetToEdit.Category != null)
            {
                tempCategoryId = widgetToEdit.Category.CategoryID;
            }
            IEnumerable<DTOContentPageForEditor> pages = _cmsService.ListPages();
            ViewData["ContentPageID"] = new SelectList(pages.OrderBy(x => x.Title), "ContentPageID", "Title", tempPageId);
            IEnumerable<ContentCategory> cats = _cmsService.ListCategories();
            ViewData["CategoryID"] = new SelectList(cats.OrderBy(x => x.Path), "CategoryID", "Path", tempCategoryId);

            //need a dropdown for active weighted content this widget can be applied to
            var allWeightedContent = _cmsService.ListWeightedContents().Where(w => w.IsModuleType.Equals(false));
            if (settingsToEdit == null)
            {
                ViewData["WeightedContentID"] = new SelectList(allWeightedContent.OrderBy(x => x.Title), "WeightedContentID", "Title");
            }
            else
            {
                ViewData["WeightedContentID"] = new SelectList(allWeightedContent.OrderBy(x => x.Title), "WeightedContentID", "Title", settingsToEdit.WeightedContentID);
            }
            var model = new BackOfficeModel
            {
                _Widget = widgetToEdit
            };
            ViewData["PageTitle"] = "Edit Wdiget";
            return View(model);
        }

        [ValidateInput(false)]
        [Authorize(Roles = "Editor, PortalAdmin")]
        public ActionResult EditWeightedContent(int? id, string allPagesValue, int? categoryID, int? contentpageId,
                                       WeightedContent weightedContentToEdit)
        {
            ViewBag.Message = "";

            if (weightedContentToEdit.Title != null)
            {
                var original = _cmsService.GetWeightedContent(weightedContentToEdit.WeightedContentID);
                original.Title = weightedContentToEdit.Title.Trim();
                original.TargetDiv = weightedContentToEdit.TargetDiv.TryTrim();
                original.ZoneName = weightedContentToEdit.ZoneName.TryTrim();
                original.Description = weightedContentToEdit.Description;
                original.IsModuleType = weightedContentToEdit.IsModuleType;
                original.IntervalSeconds = weightedContentToEdit.IntervalSeconds;
                original.Active = weightedContentToEdit.Active;
                original.ContainerClasses = weightedContentToEdit.ContainerClasses.TryTrim();
                original.FirstTransitionDelay = weightedContentToEdit.FirstTransitionDelay;

                original.AdminUser = _accountService.GetUser();
                _cmsService.EditWeightedContent(original);
                ViewBag.Message = "The weighted content was edited.";
                weightedContentToEdit = original;
            }
            else
            {
                weightedContentToEdit = _cmsService.GetWeightedContent(id.GetValueOrDefault());
            }

            var model = new BackOfficeModel
            {
                _WeightedContent = weightedContentToEdit
            };
            ViewBag.Title = "Edit Weighted Content";
            return View(model);
        }

        #endregion

        #region Editor Methods

        [Authorize(Roles = "Editor")]
        public ActionResult ManageContentCategories(int? id)
        {
            ViewData["Message"] = "";
            if (id != null)
            {
                ContentCategory categoryToDelete = _cmsService.GetContentCategory(id.GetValueOrDefault());

                if (categoryToDelete.SubCategories.Count > 0)
                {
                    Session["DeleteFailed"] = true;
                    return Redirect("/backoffice/ManageContentCategories");
                }
                else
                {
                    var allcats = _cmsService.ListAllCategories();
                    IEnumerable<ContentCategory> catsToDecrement;
                    if (categoryToDelete.ParentCategory == null)
                    {
                        catsToDecrement = allcats.Where(cat => cat.ParentCategory == null &&
                            cat.Portal.PortalID == _cacheService.GetCurrentPortal().PortalID);
                    }
                    else
                    {
                        catsToDecrement = categoryToDelete.ParentCategory.SubCategories;
                    }
                    int missingImportance = categoryToDelete.Importance;
                    int removedCatId = categoryToDelete.CategoryID;
                    if (_cmsService.DeleteContentCategory(categoryToDelete))
                    {

                        //loop through categories and decrement the importance of each
                        //category sibling with an importance greater than the just deleted category
                        foreach (var category in catsToDecrement)
                        {
                            if (category.Importance > missingImportance &&
                                category.CategoryID != removedCatId)
                            {
                                category.Importance = category.Importance - 1;
                                _cmsService.EditContentCategory(category);
                            }
                        }

                        ResetAppAuto();
                        return Redirect("/backoffice/ManageContentCategories");
                    }
                    else
                    {
                        Session["DeleteFailed"] = true;
                        return Redirect("/backoffice/ManageContentCategories");
                    }
                }
            }
            IEnumerable<ContentCategory> categories = _cmsService.ListCategories();
            if (Session["DeleteFailed"] != null)
            {
                ViewData["Message"] = "This category has child categories, modules or alternate language versions.  You must delete them first.";
                Session["DeleteFailed"] = null;
            }
            var model = new BackOfficeModel
            {
                _ContentCategories = categories
            };
            ViewData["PageTitle"] = "Manage Content Categories";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        public ActionResult PortalImageManager()
        {
            ViewData["Message"] = "";
            string foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();

            string path = Server.MapPath("~/Uploadedimages/" + foldername);
            string thumbpath = Server.MapPath("~/Uploadedimages/" + foldername + "/thumbs");

            Directory.CreateDirectory(path);
            Directory.CreateDirectory(thumbpath);
            var di = new DirectoryInfo(thumbpath);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new BackOfficeModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewData["PageTitle"] = "Image Manager";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult PortalImageManager(FormCollection forms)
        {
            ViewData["Message"] = "";
            string foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();

            string path = Server.MapPath("~/Uploadedimages/" + foldername);

            foreach (string inputTagName in Request.Files)
            {
                HttpPostedFileBase file = Request.Files[inputTagName];

                if (file.ContentLength > 0)
                {
                    string filePath = Path.Combine(path, Path.GetFileName(file.FileName));
                    string thumbPath = Path.Combine(path + "\\thumbs", Path.GetFileName(file.FileName));
                    if (file.FileName.Contains("jpg") ||
                        file.FileName.Contains("gif") ||
                        file.FileName.Contains("png"))
                    {
                        file.SaveAs(filePath);
                        //create thumbnail
                        Files.ResizeImage(filePath, thumbPath, 80, 300, false);
                    }
                    //unzip the file
                    if (file.FileName.Contains("zip"))
                    {
                        Files.Unzipfile(filePath, path);
                    }
                }
            }

            var di = new DirectoryInfo(path);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new BackOfficeModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewData["PageTitle"] = "Image Manager";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        public ActionResult ImageManager()
        {
            ViewData["Message"] = "";
            string foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();

            string path = Server.MapPath("~/Uploadedimages/" + foldername);
            string thumbpath = Server.MapPath("~/Uploadedimages/" + foldername + "/thumbs");

            Directory.CreateDirectory(path);
            Directory.CreateDirectory(thumbpath);
            var di = new DirectoryInfo(thumbpath);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new BackOfficeModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewData["PageTitle"] = "Image Manager";
            return View("ImageManager", "DontUseMaster", model);
        }

        [Authorize(Roles = "Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ImageManager(FormCollection forms)
        {
            ViewData["Message"] = "";
            string foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();

            string path = Server.MapPath("~/Uploadedimages/" + foldername);

            foreach (string inputTagName in Request.Files)
            {
                HttpPostedFileBase file = Request.Files[inputTagName];

                if (file.ContentLength > 0)
                {
                    string filePath = Path.Combine(path, Path.GetFileName(file.FileName));
                    string thumbPath = Path.Combine(path + "\\thumbs", Path.GetFileName(file.FileName));
                    if (file.FileName.Contains("jpg") ||
                        file.FileName.Contains("gif") ||
                        file.FileName.Contains("png"))
                    {
                        file.SaveAs(filePath);
                        //create thumbnail
                        Files.ResizeImage(filePath, thumbPath, 80, 300, false);
                    }
                    //unzip the file
                    if (file.FileName.Contains("zip"))
                    {
                        Files.Unzipfile(filePath, path);
                    }
                }
            }

            var di = new DirectoryInfo(path);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new BackOfficeModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewData["PageTitle"] = "Image Manager";
            return View("ImageManager", "DontUseMaster", model);
        }

        [Authorize(Roles = "Editor")]
        public ActionResult FileManager()
        {
            ViewData["Message"] = "";
            string folderName = _cacheService.GetCurrentPortal().Name.ToUrlFormat();
            string path = Server.MapPath("~/Uploadedfiles/" + folderName);

            Directory.CreateDirectory(path);
            var di = new DirectoryInfo(path);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new BackOfficeModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewData["PageTitle"] = "File Manager";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult FileManager(FormCollection forms)
        {
            ViewData["Message"] = "";

            string foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();
            string path = Server.MapPath("~/Uploadedfiles/" + foldername);

            foreach (string inputTagName in Request.Files)
            {
                HttpPostedFileBase file = Request.Files[inputTagName];

                if (file.ContentLength > 0)
                {
                    string filePath = Path.Combine(path, Path.GetFileName(file.FileName));

                    file.SaveAs(filePath);
                    //unzip the file
                    if (file.FileName.Contains("zip"))
                    {
                        Files.Unzipfile(filePath, path);
                    }
                }
            }

            var di = new DirectoryInfo(path);
            FileInfo[] rgFiles = di.GetFiles("*.*");
            var model = new BackOfficeModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Files = rgFiles
            };
            ViewData["PageTitle"] = "File Manager";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        public ActionResult ManageContentPages(int? id)
        {
            ViewData["Message"] = "";
            if (id != null)
            {
                ContentPage pageToDelete = _cmsService.GetContentPage(id.GetValueOrDefault());
                if (!_cmsService.DeleteContentPage(pageToDelete))
                {
                    ViewData["Message"] = "";
                }
            }
            IEnumerable<DTOContentPageForEditor> pages = _cmsService.ListPages();
            var model = new BackOfficeModel
            {
                _DTOContentPageForEditor = pages
            };
            ViewData["PageTitle"] = "Manage Content Pages";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        public ActionResult EditContentCategory(int id)
        {
            ContentCategory category = _cmsService.GetContentCategory(id);

            Portal currentPortal = _cacheService.GetCurrentPortal();
            if (currentPortal.PortalID != category.Portal.PortalID)
            {
                return Redirect("/backoffice/managecontentcategories");
            }

            IEnumerable<ContentCategory> categories = _cmsService.ListCategoriesForBackOffice();
            ViewData["issubcat"] = false;
            ViewData["prntcatmsg"] = "Click here to make this category a subcategory.  This can't be changed once set.";
            if (category.ParentCategory != null)
            {
                ViewData["issubcat"] = true;
                ViewData["prntcatmsg"] = "This category is currently a sub category.";
            }
            if (category.SubCategories.Count() > 0)
            {
                ViewData["prntcatmsg"] = category.ParentCategory == null
                     ? "This category is not a sub category.<br/>This category has child categories and cannot have its parent category changed."
                     : "This category is currently a sub category.<br/>This category has child categories and cannot have its parent category changed.";
            }
            var cattmp = new CategoriesAjax();
            foreach (var cat in categories)
            {
                if (cat.CategoryID != id)
                {
                    cattmp.Add(cat);
                }
            }
            ViewData["CategoryID"] = category.ParentCategory != null
                 ? new SelectList(cattmp.OrderBy(x => x.Path), "CategoryID", "Path",
                                  category.ParentCategory.CategoryID)
                 : new SelectList(cattmp.OrderBy(x => x.Path), "CategoryID", "Path");
            var model = new BackOfficeModel
            {
                _ContentCategory = category
            };
            ViewData["Message"] = "";
            ViewData["PageTitle"] = "Edit Content Category";
            return View(model);
        }


        [Authorize(Roles = "Editor")]
        public ActionResult EditHomeCategory(int id)
        {
            ContentCategory category = _cmsService.GetContentCategory(id);

            Portal currentPortal = _cacheService.GetCurrentPortal();
            if (currentPortal.PortalID != category.Portal.PortalID)
            {
                return Redirect("/backoffice/managecontentcategories");
            }

            var model = new BackOfficeModel
            {
                _ContentCategory = category
            };
            ViewData["Message"] = "";
            ViewData["PageTitle"] = "Edit Home Category";
            return View(model);
        }

        private static void BuildPath(ContentCategory parent, ref string fullpath, ref int numparents,
                                      ref string parentlist)
        {
            if (parent.ParentCategory != null)
            {
                fullpath = parent.ParentCategory.Path + "/";
                if (parent.ParentCategory.ParentList == null)
                {
                    parentlist = string.Format(",{0},", parent.ParentCategory.CategoryID);
                }
                else
                {
                    parentlist = parent.ParentCategory.ParentList + parent.ParentCategory.CategoryID + ",";
                }
                numparents = numparents + parent.ParentCategory.NumberOfParents.GetValueOrDefault();
            }
        }

        [Authorize(Roles = "Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditContentCategory(int id, string masterName, string themeName, string description, string title, string subPageHeader, bool showinnav,
                                                bool onlyForMembers, string onlyForMembersRoles, bool requireSSL, bool isSubCategory, int? categoryId, string externalURL)
        {
            ViewData["message"] = "";
            bool isExistingSubCategory = false;
            IEnumerable<ContentCategory> categories = _cmsService.ListCategoriesForBackOffice();
            bool resetApp = false;

            ContentCategory categoryToEdit = _cmsService.GetContentCategory(id);
            int missingImportance = categoryToEdit.Importance;
            if (categoryToEdit.ParentCategory != null)
            {
                isExistingSubCategory = true;
            }

            categoryToEdit.Title = title;
            if (isSubCategory && categoryId != null)
            {
                int maxCategoryImportance = 0;
                var siblingSubCategories = _cmsService.ListSubCategories(categoryId.GetValueOrDefault());
                if (siblingSubCategories.Count() > 0)
                {
                    maxCategoryImportance = siblingSubCategories.OrderByDescending(c => c.Importance).First().Importance + 1;
                }
                else
                {
                    maxCategoryImportance = 1;
                }
                categoryToEdit.Importance = maxCategoryImportance;
                categoryToEdit.ParentCategory = _cmsService.GetContentCategory(categoryId.GetValueOrDefault());

                //This is only done if the category previously had no parent or children
                //TODO a future may provide a 301 redirect and rebuild child routes if it is desired to change an existing path.

                //Build the path
                if (!isExistingSubCategory && categoryToEdit.SubCategories.Count() == 0)
                {
                    resetApp = true;
                    string newCategoryPath = categoryToEdit.Path;
                    string fullPath = "";
                    int numberOfParents = 1;
                    string parentList = "";
                    BuildPath(categoryToEdit, ref fullPath, ref numberOfParents, ref parentList);
                    categoryToEdit.Path = fullPath + newCategoryPath;
                    categoryToEdit.SinglePath = newCategoryPath;
                    categoryToEdit.NumberOfParents = numberOfParents;
                    categoryToEdit.ParentList = parentList;
                }
            }
            else
            {
                if (!isExistingSubCategory)
                {
                    categoryToEdit.ParentCategory = null;
                }
            }
            isSubCategory = isExistingSubCategory;
            ViewData["issubcat"] = isSubCategory;

            categoryToEdit.ShowInNav = !isSubCategory && showinnav;
            categoryToEdit.Description = description;
            categoryToEdit.SubPageHeader = subPageHeader;
            categoryToEdit.OnlyForMembers = onlyForMembers;
            categoryToEdit.RequireSSL = requireSSL;
            categoryToEdit.ExternalURL = externalURL;
            categoryToEdit.ThemeName = themeName;
            categoryToEdit.MasterName = masterName;
            categoryToEdit.OnlyForMembersRoles = onlyForMembersRoles;
            //decrement the categories at this level with a greater importance than the one
            //just made a subcategory if this was a move down the hierarchy (moving up the hierarchy is not currently allowed)

            var allCategories = _cmsService.ListAllCategories();
            IEnumerable<ContentCategory> catsToDecrement;
            if (!isExistingSubCategory)
            {
                catsToDecrement = allCategories.Where(cat => cat.ParentCategory == null &&
                    cat.Portal.PortalID == _cacheService.GetCurrentPortal().PortalID);
            }
            else
            {
                catsToDecrement = categoryToEdit.ParentCategory.SubCategories;
            }

            int removedCategoryId = categoryToEdit.CategoryID;
            if (_cmsService.EditContentCategory(categoryToEdit))
            {
                ViewData["Message"] = "Update Successfull";
                //loop through categories and decrement the importance of each
                //category sibling with an importance greater than the just deleted category
                if (resetApp)
                {
                    foreach (var category in catsToDecrement)
                    {
                        if (category.Importance > missingImportance &&
                            category.CategoryID != removedCategoryId)
                        {
                            category.Importance = category.Importance - 1;
                            _cmsService.EditContentCategory(category);
                        }
                    }
                    ResetAppAuto();
                }
            }
            else
            {
                ViewData["Message"] = "There was a problem updating the category.";
                categoryToEdit.Path = categoryToEdit.SinglePath;
                categoryToEdit.ParentCategory = null;
                ViewData["issubcat"] = false;
            }
            ViewData["prntcatmsg"] = "Click here to make this category a subcategory.";
            if (categoryToEdit.SubCategories.Count() > 0)
            {
                ViewData["prntcatmsg"] = categoryToEdit.ParentCategory == null
                                             ? "This category is not a sub category.<br/>This category has child categories and cannot have its parent category changed."
                                             : "This category is currently a sub category.<br/>This category has child categories and cannot have its parent category changed.";
            }
            else
            {
                if (categoryToEdit.ParentCategory != null)
                {
                    ViewData["prntcatmsg"] = "This category is currently a sub category.";
                }
            }
            var catTemp = categories.Where(cat4List => cat4List.CategoryID != id);

            ViewData["CategoryID"] = categoryToEdit.ParentCategory != null
                                         ? new SelectList(catTemp.OrderBy(x => x.Path), "CategoryID", "Path",
                                                          categoryToEdit.ParentCategory.CategoryID)
                                         : new SelectList(catTemp.OrderBy(x => x.Path), "CategoryID", "Path");
            ViewData["PageTitle"] = "Edit Category";
            var model = new BackOfficeModel
            {
                _ContentCategory = categoryToEdit
            };

            return View(model);
        }

        [Authorize(Roles = "Editor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditHomeCategory(int id, string description, string title, string subPageHeader)
        {
            ViewData["message"] = "";
            ContentCategory categoryToEdit = _cmsService.GetContentCategory(id);
            categoryToEdit.Description = description;
            categoryToEdit.Title = title;
            categoryToEdit.SubPageHeader = subPageHeader;
            if (_cmsService.EditContentCategoryNoValidation(categoryToEdit))
            {
                ViewData["Message"] = "Update Successfull";
            }
            else
            {
                ViewData["Message"] = "There was a problem updating the category.";
            }
            ViewData["PageTitle"] = "Edit Home Category";
            var model = new BackOfficeModel
            {
                _ContentCategory = categoryToEdit
            };
            return View(model);
        }

        [Authorize(Roles = "Editor, Contributor")]
        public ActionResult EditContentPage(int id)
        {
            var currentPortal = _cacheService.GetCurrentPortal();
            ContentPage contentPage = _cmsService.GetContentPage(id);
            contentPage.Portal = _portalService.GetPortal(currentPortal.PortalID);
            var user = _accountService.GetUser();
            if (Request.UrlReferrer != null)
            {
                ViewData["editpagelink"] = Request.UrlReferrer.ToString();
            }
            else
            {
                ViewData["editpagelink"] = "/";
            }

            if (Roles.IsUserInRole("Contributor") && !Roles.IsUserInRole("Editor"))
            {
                if (contentPage.Contributor.UserName != user.UserName)
                {
                    RedirectToAction("Logon", "Account");
                }
            }

            ViewData["message"] = "";
            return View("EditContentPage", "EditPage", contentPage);
        }

        [Authorize(Roles = "Editor, Contributor")]
        [ValidateInput(false)]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditContentPage(int id, string body, string editpagelink)
        {
            ContentPage originalContentPage = _cmsService.GetContentPage(id);
            originalContentPage.Body = body;
            var user = _accountService.GetUser();
            if (Roles.IsUserInRole("Contributor") && !Roles.IsUserInRole("Editor"))
            {
                if (originalContentPage.Contributor.UserName != user.UserName)
                {
                    RedirectToAction("Logon", "Account");
                }
            }

            _cmsService.EditContentPage(originalContentPage);
            ViewData["editpagelink"] = editpagelink;
            ViewData["message"] = "Update Successful";
            return View("EditContentPage", "EditPage", originalContentPage);
        }

        [Authorize(Roles = "Editor, Admin")]
        public ActionResult EditCss()
        {
            var currentPortal = _cacheService.GetCurrentPortal();
            var themePath = "~/content/app_themes/";
            if (currentPortal.IsRazor)
            {
                themePath = "~/RazorThemes/";
            }

            string filewpath = Server.MapPath(themePath + _cacheService.GetCurrentPortal().SkinName + "/css/Site.css");

            ViewData["csstext"] = System.IO.File.ReadAllText(filewpath);
            ViewData["filewpath"] = filewpath;

            ViewData["editpagelink"] = Request.UrlReferrer.ToString();
            ViewData["message"] = "";
            return View("EditCss", "EditPage");
        }

        [Authorize(Roles = "Editor, Admin")]
        [ValidateInput(false)]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditCss(string cssbody, string editpagelink, string filewpath)
        {
            System.IO.File.WriteAllText(filewpath, cssbody);
            ViewData["csstext"] = cssbody;
            ViewData["editpagelink"] = editpagelink;
            ViewData["filewpath"] = filewpath;
            ViewData["message"] = "Update Successful";
            return View("EditCss", "EditPage");
        }

        [Authorize(Roles = "Editor, Contributor")]
        [ValidateInput(false)]
        public ActionResult CreateContentPage(int? categoryId, [Bind(Exclude = "ContentPageID")] ContentPage contentpageToCreate)
        {
            ViewData["PageTitle"] = "Create Content Page";
            ViewData["message"] = "";
            IEnumerable<ContentCategory> categories = _cmsService.BuildCategoryListForBackOffice(_cmsService.ListCategories());
            if (contentpageToCreate.Title != null)
            {
                contentpageToCreate.AddedDate = DateTime.Now;
                var user = _accountService.GetUser();
                var contentcategory = new ContentCategory
                {
                    CategoryID = categoryId.GetValueOrDefault()
                };

                contentpageToCreate.Contributor = user;
                contentpageToCreate.Editor = user;
                contentpageToCreate.AddedDate = DateTime.Now;
                contentpageToCreate.ReleaseDate = DateTime.Now;
                contentpageToCreate.ExpireDate = DateTime.Parse("12/12/2012");
                contentpageToCreate.Approved = true;
                contentpageToCreate.Listed = true;
                contentpageToCreate.CommentsEnabled = false;
                contentpageToCreate.OnlyForMembers = false;
                contentpageToCreate.IsSubPage = true;
                contentpageToCreate.ViewCount = 0;
                contentpageToCreate.Votes = 0;
                contentpageToCreate.TotalRating = 0;
                contentpageToCreate.IsCategoryPage = false;
                contentpageToCreate.AnonCommentsEnabled = false;
                contentpageToCreate.ViewCount = 0;

                if (_cacheService.GetCurrentPortal().UsesWikiForCMS)
                {
                    contentpageToCreate.UseWikiMarkup = true;
                }
                else
                {
                    contentpageToCreate.UseWikiMarkup = false;
                }
                contentpageToCreate.Language = _portalService.GetPortal(_cacheService.GetCurrentPortal().PortalID).DefaultLanguage;
                contentpageToCreate.OnlyForPayingMembers = false;
                contentpageToCreate.TotalRating = 0;
                contentpageToCreate.ReleaseDate = DateTime.Now;
                contentpageToCreate.ShowContributorLink = true;

                IEnumerable<ContentPage> pages = _cmsService.ListCategoryPagesByCategory(contentcategory.CategoryID);
                int maximp = 0;
                foreach (ContentPage page in pages)
                {
                    if (page.Importance > maximp)
                    {
                        maximp = page.Importance.GetValueOrDefault();
                    }
                }

                contentpageToCreate.Importance = maximp;
                contentpageToCreate.Description = "";

                contentpageToCreate.ContentCategory = contentcategory;

                int result = _cmsService.CreateContentPage(contentpageToCreate);
                if (result != 0)
                {
                    return RedirectToAction("EditContentPage", new { id = result });
                }
                else
                {
                    var modelState = _cmsService.GetModelStateDictionary();
                    this.ModelState.Merge(modelState);
                    ViewData["Message"] = "";
                }
                ViewData["CategoryID"] = new SelectList(categories, "CategoryID", "Title");
                return View("CreateContentPage");
            }

            ViewData["CategoryID"] = new SelectList(categories, "CategoryID", "Title");

            return View("CreateContentPage");
        }

        [Authorize(Roles = "Editor")]
        public ActionResult SetPublishedPage(int? id, int? selectedpageId)
        {
            if (id == null)
            {
                id = 0;
            }
            if (selectedpageId.HasValue)
            {
                _cmsService.SetPublishedPage(selectedpageId.GetValueOrDefault());
            }

            ContentCategory currentcat = _cmsService.GetContentCategory(id.GetValueOrDefault());
            id = currentcat.CategoryID;

            IEnumerable<ContentPage> pages = _cmsService.ListCategoryPagesByCategory(id.GetValueOrDefault());
            List<ContentPage> pagesinorder = pages.OrderBy(contentPage => contentPage.Title).ToList();

            IEnumerable<ContentCategory> contentcategories = _cmsService.BuildCategoryListForBackOffice(_cmsService.ListCategories());

            var model = new BackOfficeModel
            {
                _ContentCategory = currentcat,
                _ContentPages = pagesinorder,
                _ContentCategories = contentcategories
            };
            ViewData["currentcat"] = currentcat.Title;
            ViewData["PageTitle"] = "Set Published Page For Content Categories";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        public ActionResult ResetApp()
        {
            Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
            var httpRuntimeSection = (HttpRuntimeSection)config.GetSection("system.web/httpRuntime");
            httpRuntimeSection.Enable = false;
            config.Save(ConfigurationSaveMode.Minimal);

            httpRuntimeSection.Enable = true;
            config.Save(ConfigurationSaveMode.Minimal);

            ViewData["Message"] = "";

            IEnumerable<ContentCategory> categories = _cmsService.ListCategories();
            var model = new BackOfficeModel
            {
                _ContentCategories = categories
            };
            ViewData["PageTitle"] = "Manage Content Categories";

            return View("ManageContentCategories", model);
        }

        #endregion

        #region Contributor/Editor Methods

        [Authorize(Roles = "Contributor, Editor")]
        public ActionResult ManageContent()
        {
            ViewData["Message"] = "";
            IEnumerable<DTOContentPageForEditor> pages = null;
            if (Roles.IsUserInRole("Contributor"))
            {
                var user = _accountService.GetUser();
                pages = _cmsService.ListPages(user.UserID);
            }
            if (Roles.IsUserInRole("Editor"))
            {
                pages = _cmsService.ListPages();
            }
            var model = new BackOfficeModel
            {
                _DTOContentPageForEditor = pages
            };
            ViewData["PageTitle"] = "Manage Content";
            return View(model);
        }

        [Authorize(Roles = "Editor")]
        public ActionResult CreateContentCategory([Bind(Exclude = "CategoryID")] ContentCategory contentCategoryToCreate, bool? isSubCategory, int? categoryId)
        {
            ViewData["PageTitle"] = "Create Content Category";
            ViewData["message"] = "";

            IEnumerable<ContentCategory> categories = _cmsService.ListCategoriesForBackOffice();
            ViewData["CategoryID"] = new SelectList(categories.OrderBy(x => x.Path), "CategoryID", "Path");

            if (contentCategoryToCreate.Title != null)
            {

                contentCategoryToCreate.Path = contentCategoryToCreate.Title.ToUrlFormat();
                contentCategoryToCreate.SinglePath = contentCategoryToCreate.Title.ToUrlFormat();

                if (isSubCategory.HasValue)
                {
                    if (isSubCategory.GetValueOrDefault() && categoryId != null)
                    {
                        contentCategoryToCreate.ParentCategory = _cmsService.GetContentCategory(categoryId.GetValueOrDefault());

                        string newCategoryPath = contentCategoryToCreate.Path;
                        string fullPath = "";
                        int numberOfParents = 1;
                        string parentList = "";
                        BuildPath(contentCategoryToCreate, ref fullPath, ref numberOfParents, ref parentList);
                        contentCategoryToCreate.Path = fullPath + newCategoryPath;
                        contentCategoryToCreate.SinglePath = newCategoryPath;
                        contentCategoryToCreate.NumberOfParents = numberOfParents;
                        contentCategoryToCreate.ParentList = parentList;
                    }
                }
                contentCategoryToCreate.AddedDate = DateTime.Now;
                contentCategoryToCreate.NumberOfParents = 0;
                var user = _accountService.GetUser();

                contentCategoryToCreate.Editor = user;
                contentCategoryToCreate.AddedDate = DateTime.Now;

                //set the importance for the new category
                int maxCategoryImportance = 0;

                if (isSubCategory.GetValueOrDefault())
                {
                    var siblingSubCategories = _cmsService.ListSubCategories(categoryId.GetValueOrDefault());
                    if (siblingSubCategories.Count()>0)
                    {
                        maxCategoryImportance = siblingSubCategories.OrderByDescending(c => c.Importance).First().Importance + 1;
                    }
                    else
                    {
                        maxCategoryImportance = 1;
                    }
                }
                else
                {
                    var siblingCategories = _cmsService.ListCategories();
                    if (siblingCategories.Count() > 0)
                    {
                        maxCategoryImportance = siblingCategories.OrderByDescending(c => c.Importance).First().Importance + 1;
                    }
                    else
                    {
                        maxCategoryImportance = 1;
                    }
                }

                contentCategoryToCreate.Importance = maxCategoryImportance;
                int createdCategoryId = _cmsService.CreateContentCategory(contentCategoryToCreate);
                if (createdCategoryId == 0)
                {
                    var modelState = _cmsService.GetModelStateDictionary();
                    this.ModelState.Merge(modelState);

                    ViewData["message"] = "";
                    return View("CreateContentCategory");
                }

                ResetAppAuto();
                return RedirectToAction("EditContentCategory", new { id = createdCategoryId });
            }

            return View("CreateContentCategory");
        }

        #endregion

        #region Email Template Methods

        [ValidateInput(false)]
        [Authorize(Roles = "Editor,Admin")]
        public ActionResult EditEmailTemplate(string source, string editedEmailID)
        {
            var user = _accountService.GetUser();
            var templates = _portalService.ListEmailTemplates();
            if (templates.Count() > 0)
            {
                var template = templates
                    .Where(t => t.Name.Equals(editedEmailID)).FirstOrDefault();
                if (template != null)
                {
                    template.Body = source;
                    template.UpdateDate = DateTime.Now;
                    template.Editor = user;
                    _portalService.EditEmailTemplate(template);
                }
                else
                {
                    template = new EmailTemplate();
                    template.Body = source;
                    template.AddedDate = DateTime.Now;
                    template.UpdateDate = DateTime.Now;
                    template.Editor = user;
                    template.Name = editedEmailID;
                    _portalService.CreateEmailTemplate(template);
                }
            }
            else
            {
                var template = new EmailTemplate();
                template.Body = source;
                template.Name = editedEmailID;
                template.AddedDate = DateTime.Now;
                template.UpdateDate = DateTime.Now;
                template.Editor = user;
                _portalService.CreateEmailTemplate(template);
            }
            ViewData["message"] = "Template Updated";
            return RedirectToAction("EditEmailTemplates");
        }

        private MacroFormatter GetFormatter()
        {
            var siteRenderers = new IRenderer[]
            {
                new TitleLinkRenderer(Url),
                new TextColorRenderer(),
                new TextSizeRenderer(),
                new AnyStyleRenderer(),
            };
            IEnumerable<IRenderer> allRenderers = Renderers.All.Union(siteRenderers);
            return new MacroFormatter(allRenderers);
        }

        [Authorize(Roles = "Editor,Admin")]
        public ActionResult EditEmailTemplates()
        {
            ViewData["Message"] = "";
            ViewData["PageTitle"] = "Edit Email Templates";

            var templates = _portalService.ListEmailTemplates();

            ViewData["CommentReply"] = "";
            ViewData["Welcome"] = "";
            ViewData["ResetPassword"] = "";
            ViewData["Confirmation"] = "";

            if (templates.Count() > 0)
            {
                var template = templates.Where(
                    t => t.Name == "Confirmation")
                    .FirstOrDefault();
                if (template != null) { ViewData["Confirmation"] = _wikiEngine.Render(template.Body, GetFormatter()); }

                template = templates.Where(
                    t => t.Name == "CommentReply")
                    .FirstOrDefault();
                if (template != null) { ViewData["CommentReply"] = _wikiEngine.Render(template.Body, GetFormatter()); }

                template = templates.Where(
                    t => t.Name == "Welcome")
                    .FirstOrDefault();
                if (template != null) { ViewData["Welcome"] = _wikiEngine.Render(template.Body, GetFormatter()); }

                template = templates.Where(
                    t => t.Name == "ResetPassword")
                    .FirstOrDefault();
                if (template != null) { ViewData["ResetPassword"] = _wikiEngine.Render(template.Body, GetFormatter()); }
            }

            var model = new BackOfficeModel
            {
                _EmailTemplates = templates,
            };
            return View(model);
        }

        #endregion
    }

}